package com.bi.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bi.entity.ComponentLibrary;
import com.bi.entity.DataComponent;
import com.bi.entity.ChartComponent;
import com.bi.mapper.ComponentLibraryMapper;
import com.bi.service.ComponentLibraryService;
import com.bi.service.DataComponentService;
import com.bi.service.ChartComponentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 组件库服务实现类
 * 
 * @author BI Platform Team
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ComponentLibraryServiceImpl extends ServiceImpl<ComponentLibraryMapper, ComponentLibrary> implements ComponentLibraryService {

    private final DataComponentService dataComponentService;
    private final ChartComponentService chartComponentService;

    @Override
    public IPage<ComponentLibrary> getComponentLibraryPage(long current, long size, Map<String, Object> params) {
        Page<ComponentLibrary> page = new Page<>(current, size);
        return baseMapper.selectComponentLibraryPage(page, params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean publishComponent(ComponentLibrary componentLibrary) {
        try {
            // 设置发布时间
            componentLibrary.setCreateTime(LocalDateTime.now());
            componentLibrary.setUpdateTime(LocalDateTime.now());
            componentLibrary.setStatus(ComponentLibrary.LibraryStatus.PUBLISHED);
            componentLibrary.setUsageCount(0);
            componentLibrary.setRating(0.0);
            
            // 生成版本号
            if (componentLibrary.getVersion() == null || componentLibrary.getVersion().isEmpty()) {
                componentLibrary.setVersion("1.0.0");
            }
            
            // 保存到组件库
            boolean saveResult = save(componentLibrary);
            
            log.info("发布组件到组件库成功: id={}, name={}", componentLibrary.getId(), componentLibrary.getName());
            return saveResult;

        } catch (Exception e) {
            log.error("发布组件到组件库失败: name={}, error={}", componentLibrary.getName(), e.getMessage(), e);
            throw new RuntimeException("发布组件失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeFromLibrary(Long id) {
        try {
            // 软删除，设置状态为已删除
            ComponentLibrary library = getById(id);
            if (library == null) {
                throw new RuntimeException("组件库记录不存在");
            }
            
            library.setStatus(ComponentLibrary.LibraryStatus.DELETED);
            library.setUpdateTime(LocalDateTime.now());
            
            boolean updateResult = updateById(library);
            
            log.info("从组件库删除组件成功: id={}", id);
            return updateResult;

        } catch (Exception e) {
            log.error("从组件库删除组件失败: id={}, error={}", id, e.getMessage(), e);
            throw new RuntimeException("删除组件失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateComponentLibrary(ComponentLibrary componentLibrary) {
        try {
            componentLibrary.setUpdateTime(LocalDateTime.now());
            boolean updateResult = updateById(componentLibrary);
            
            log.info("更新组件库信息成功: id={}, name={}", componentLibrary.getId(), componentLibrary.getName());
            return updateResult;

        } catch (Exception e) {
            log.error("更新组件库信息失败: id={}, error={}", componentLibrary.getId(), e.getMessage(), e);
            throw new RuntimeException("更新组件库信息失败: " + e.getMessage());
        }
    }

    @Override
    public List<ComponentLibrary> getComponentsByCategory(Long categoryId) {
        return baseMapper.selectByCategoryId(categoryId);
    }

    @Override
    public List<ComponentLibrary> getComponentsByType(String componentType) {
        return baseMapper.selectByComponentType(componentType);
    }

    @Override
    public List<ComponentLibrary> getComponentsByTags(List<String> tags) {
        return baseMapper.selectByTags(tags);
    }

    @Override
    public List<ComponentLibrary> searchComponents(String keyword, String componentType, Long categoryId) {
        return baseMapper.searchComponents(keyword, componentType, categoryId);
    }

    @Override
    public List<ComponentLibrary> getRecommendedComponents(Integer limit) {
        return baseMapper.selectRecommendedComponents(limit != null ? limit : 10);
    }

    @Override
    public List<ComponentLibrary> getPopularComponents(Integer limit) {
        return baseMapper.selectPopularComponents(limit != null ? limit : 10);
    }

    @Override
    public Map<String, Object> getLibraryStatistics() {
        return baseMapper.selectLibraryStatistics();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean useComponent(Long componentId) {
        try {
            int updateResult = baseMapper.incrementUsageCount(componentId);
            log.info("更新组件使用次数成功: componentId={}", componentId);
            return updateResult > 0;
        } catch (Exception e) {
            log.error("更新组件使用次数失败: componentId={}, error={}", componentId, e.getMessage());
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rateComponent(Long componentId, Double rating) {
        try {
            int updateResult = baseMapper.updateRating(componentId, rating);
            log.info("更新组件评分成功: componentId={}, rating={}", componentId, rating);
            return updateResult > 0;
        } catch (Exception e) {
            log.error("更新组件评分失败: componentId={}, rating={}, error={}", componentId, rating, e.getMessage());
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComponentLibrary copyToLibrary(Long sourceComponentId, String componentType, Long categoryId) {
        try {
            ComponentLibrary library = new ComponentLibrary();
            
            if ("DATA_COMPONENT".equals(componentType)) {
                DataComponent dataComponent = dataComponentService.getById(sourceComponentId);
                if (dataComponent == null) {
                    throw new RuntimeException("源数据组件不存在");
                }
                
                library.setName(dataComponent.getName() + "_library");
                library.setDisplayName(dataComponent.getDisplayName() + "_组件库");
                library.setDescription(dataComponent.getDescription());
                library.setComponentType(ComponentLibrary.ComponentType.DATA_COMPONENT);
                library.setComponentId(sourceComponentId);
                
            } else if ("CHART_COMPONENT".equals(componentType)) {
                ChartComponent chartComponent = chartComponentService.getById(sourceComponentId);
                if (chartComponent == null) {
                    throw new RuntimeException("源图表组件不存在");
                }
                
                library.setName(chartComponent.getName() + "_library");
                library.setDisplayName(chartComponent.getDisplayName() + "_组件库");
                library.setDescription(chartComponent.getDescription());
                library.setComponentType(ComponentLibrary.ComponentType.CHART_COMPONENT);
                library.setComponentId(sourceComponentId);
            } else {
                throw new RuntimeException("不支持的组件类型: " + componentType);
            }
            
            library.setCategoryId(categoryId);
            library.setLibraryType(ComponentLibrary.LibraryType.CUSTOM);
            library.setVersion("1.0.0");
            library.setIsPublic(false);
            library.setIsRecommended(false);
            library.setUsageCount(0);
            library.setRating(0.0);
            library.setStatus(ComponentLibrary.LibraryStatus.DRAFT);
            library.setCreator("current_user");
            
            boolean saveResult = save(library);
            if (!saveResult) {
                throw new RuntimeException("保存到组件库失败");
            }
            
            log.info("复制组件到组件库成功: sourceId={}, libraryId={}", sourceComponentId, library.getId());
            return library;

        } catch (Exception e) {
            log.error("复制组件到组件库失败: sourceId={}, type={}, error={}", sourceComponentId, componentType, e.getMessage(), e);
            throw new RuntimeException("复制组件失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> createFromLibrary(Long libraryId, String newName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ComponentLibrary library = getById(libraryId);
            if (library == null) {
                throw new RuntimeException("组件库记录不存在");
            }
            
            // 增加使用次数
            useComponent(libraryId);
            
            if (library.getComponentType() == ComponentLibrary.ComponentType.DATA_COMPONENT) {
                DataComponent newComponent = dataComponentService.copyComponent(library.getComponentId(), newName);
                result.put("success", true);
                result.put("componentType", "DATA_COMPONENT");
                result.put("componentId", newComponent.getId());
                result.put("message", "从组件库创建数据组件成功");
                
            } else if (library.getComponentType() == ComponentLibrary.ComponentType.CHART_COMPONENT) {
                ChartComponent newComponent = chartComponentService.copyChartComponent(library.getComponentId(), newName);
                result.put("success", true);
                result.put("componentType", "CHART_COMPONENT");
                result.put("componentId", newComponent.getId());
                result.put("message", "从组件库创建图表组件成功");
                
            } else {
                throw new RuntimeException("不支持的组件类型");
            }
            
            log.info("从组件库创建组件成功: libraryId={}, newName={}", libraryId, newName);

        } catch (Exception e) {
            log.error("从组件库创建组件失败: libraryId={}, newName={}, error={}", libraryId, newName, e.getMessage(), e);
            result.put("success", false);
            result.put("message", "创建组件失败: " + e.getMessage());
        }
        
        return result;
    }

    @Override
    public Map<String, Object> exportLibrary(List<Long> libraryIds) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 简化实现，实际需要导出完整的组件配置
            List<ComponentLibrary> libraries = listByIds(libraryIds);
            
            result.put("success", true);
            result.put("data", libraries);
            result.put("count", libraries.size());
            result.put("message", "导出组件库成功");
            
            log.info("导出组件库成功: count={}", libraries.size());

        } catch (Exception e) {
            log.error("导出组件库失败: libraryIds={}, error={}", libraryIds, e.getMessage(), e);
            result.put("success", false);
            result.put("message", "导出失败: " + e.getMessage());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importLibrary(Map<String, Object> importData) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 简化实现，实际需要解析导入数据并创建组件
            result.put("success", true);
            result.put("message", "导入组件库功能开发中");
            
            log.info("导入组件库: dataSize={}", importData.size());

        } catch (Exception e) {
            log.error("导入组件库失败: error={}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "导入失败: " + e.getMessage());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean syncComponentInfo(Long libraryId) {
        try {
            ComponentLibrary library = getById(libraryId);
            if (library == null) {
                throw new RuntimeException("组件库记录不存在");
            }
            
            // 同步组件信息
            if (library.getComponentType() == ComponentLibrary.ComponentType.DATA_COMPONENT) {
                DataComponent dataComponent = dataComponentService.getById(library.getComponentId());
                if (dataComponent != null) {
                    library.setDisplayName(dataComponent.getDisplayName());
                    library.setDescription(dataComponent.getDescription());
                }
            } else if (library.getComponentType() == ComponentLibrary.ComponentType.CHART_COMPONENT) {
                ChartComponent chartComponent = chartComponentService.getById(library.getComponentId());
                if (chartComponent != null) {
                    library.setDisplayName(chartComponent.getDisplayName());
                    library.setDescription(chartComponent.getDescription());
                }
            }
            
            library.setUpdateTime(LocalDateTime.now());
            boolean updateResult = updateById(library);
            
            log.info("同步组件信息成功: libraryId={}", libraryId);
            return updateResult;

        } catch (Exception e) {
            log.error("同步组件信息失败: libraryId={}, error={}", libraryId, e.getMessage(), e);
            return false;
        }
    }
}